package com.xsedge.xsedge.tools;/*
 * @Author ljc
 * @Description //TODO ssh连接服务器
 * @Param $
 * @return $
 **/

import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.channel.ClientChannelEvent;
import org.apache.sshd.client.future.ConnectFuture;
import org.apache.sshd.client.keyverifier.DefaultKnownHostsServerKeyVerifier;
import org.apache.sshd.client.keyverifier.KnownHostsServerKeyVerifier;
import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.future.WaitableFuture;
import org.apache.sshd.common.util.io.NoCloseInputStream;
import org.apache.sshd.common.util.io.NoCloseOutputStream;

import java.io.*;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.util.Collections;
import java.util.Set;

public class SSHTools {


	public static void main(String[] args) throws IOException {
		//final String pk = readPemFile(new File("src/main/resources/ssh/id_rsa"));
		String cmds = "docker run -d -p 8021:8080 csbtang/myweb:0.1";
		System.out.println(sshConnection("101.201.155.125", 6000, "xsedge", false, cmds));
	}






	/**
	 * 读取文件内容
	 */
	public static String readPemFile(File f) throws IOException {
		try (InputStream is = Files.newInputStream(f.toPath());
		     DataInputStream dis = new DataInputStream(is)) {
			byte[] bytes = new byte[(int) f.length()];
			dis.readFully(bytes);
			return new String(bytes);
		} catch (InvalidPathException e) {
			throw new IOException(e);
		}
	}

	/**
	 * 获取密钥对
	 * @return
	 */
	static KeyPair getKeyPairFromString(String pk) throws IOException, NoSuchAlgorithmException {
		final KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
		final KeyPair keyPair = rsa.generateKeyPair();
		final ByteArrayOutputStream stream = new ByteArrayOutputStream();
		stream.write(pk.getBytes());
		final ObjectOutputStream o = new ObjectOutputStream(stream);
		o.writeObject(keyPair);
		return keyPair;
	}

	/**
	 * SSH连接
	 */
	public static String sshConnection(String host, int port, String user,
	                                final boolean strictHostKey, String cmds) throws IOException {
		try (SshClient client = SshClient.setUpDefaultClient()) {

			KnownHostsServerKeyVerifier verifier = new DefaultKnownHostsServerKeyVerifier(new ServerKeyVerifier() {
				@Override
				public boolean verifyServerKey(ClientSession clientSession, SocketAddress remoteAddress,
				                               PublicKey serverKey) {
					return !strictHostKey;
				}
			}, true);

			client.setServerKeyVerifier(verifier);
			client.start();

			ConnectFuture cf = client.connect(user, host, port);
			cf.await();
			ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
			PrintStream out = new PrintStream( byteOut,true,"gbk");
			try (ClientSession session = cf.getSession()) {
				// 这里可以加多个
//                for (KeyPair pair : provider.getKeys()) {
//                    session.addPublicKeyIdentity(pair);
//                }
				// 只要主机配了免密，这里不加也可以
				//session.addPublicKeyIdentity(getKeyPairFromString(privateKey));
				session.auth().verify(10000L);

				// 这里命令可以传进来
				try (ClientChannel channel = session.createExecChannel(cmds)) {
					channel.setIn(new NoCloseInputStream(System.in));
					channel.setOut(new NoCloseOutputStream(out));
					channel.setErr(new NoCloseOutputStream(System.err));
					WaitableFuture wf = channel.open();
					wf.await();

					Set<ClientChannelEvent> waitMask =
							channel.waitFor(Collections.singletonList(ClientChannelEvent.CLOSED), 0L);


					if (waitMask.contains(ClientChannelEvent.TIMEOUT)) {
						System.err.println("超时");
					}
					return byteOut.toString();
				}
			} finally {
				System.out.println("cmd输出： " + byteOut.toString());
				client.stop();
			}
		}
	}



}